//
//  MWPhotoBrowser.m
//  MWPhotoBrowser
//
//  Created by Michael Waterfall on 14/10/2010.
//  Copyright 2010 d3i. All rights reserved.
//

#import <QuartzCore/QuartzCore.h>
#import "MWPhotoBrowser.h"
#import "MWZoomingScrollView.h"
#import "MBProgressHUD.h"
#import "SDImageCache.h"
#import "UIImageView+WebCache.h"
#import "TopSinglePixelLineView.h"

#ifndef RGB
#define RGB(r, g, b) [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1]
#define RGBA(r, g, b, a) [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:a]
#endif

#define SYSTEM_VERSION_EQUAL_TO(v)                  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
#define SYSTEM_VERSION_GREATER_THAN(v)              ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v)                 ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v)     ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)

#define PADDING                 10
#define PAGE_INDEX_TAG_OFFSET   1000
#define PAGE_INDEX(page)        ([(page) tag] - PAGE_INDEX_TAG_OFFSET)

#define SLIDE_SHOW_INTERVAL_COUNG     5


#define  QW_DELETE_STICKER_IMAGE_IN_BROWSER_TAG  2346237
// Private
@interface MWPhotoBrowser () {
    
    // Data
    id <MWPhotoBrowserDelegate> _delegate;
    NSUInteger _photoCount;
    NSMutableArray *_photos;
    NSArray *_depreciatedPhotoData; // Depreciated
    
    // Views
    UIScrollView *_pagingScrollView;
    
    // Paging
    NSMutableSet *_visiblePages, *_recycledPages;
    NSUInteger _currentPageIndex;
    NSUInteger _pageIndexBeforeRotation;
    
    // Navigation & controls
    UIButton *_backBtn;
    UIButton *_deleteBtn;
    UIButton *_selectionBtn;
    UIButton *_selectionDoneBtn;
    UIToolbar *_toolbar;
    NSTimer *_controlVisibilityTimer;
    NSTimer * _controlSlideShowTimer;
    UIBarButtonItem *_actionButton, *_commentButton, *_likeButton;
    UIActionSheet *_actionsSheet;
    MBProgressHUD *_progressHUD;
    
    UIButton *_exifInfoBtn;
    
    // Appearance
    UIImage *_navigationBarBackgroundImageDefault,
    *_navigationBarBackgroundImageLandscapePhone;
    UIColor *_previousNavBarTintColor;
    UIBarStyle _previousNavBarStyle;
    UIStatusBarStyle _previousStatusBarStyle;
    UIBarButtonItem *_previousViewControllerBackButton;
    
    UIView *commentViewContainer;
    NSMutableDictionary * commentDataCacheDic;
    
    // Misc
    BOOL _displayActionButton;
    BOOL _displayEnterTripButton;
    BOOL _displayLikeButton;
    BOOL _displayCommentButton;
    BOOL _displayCommentView;
    BOOL _displaySlideShowButton;
    
    BOOL _performingLayout;
    BOOL _rotating;
    BOOL _viewIsActive; // active as in it's in the view heirarchy
    BOOL _didSavePreviousStateOfNavBar;
    
    BOOL isSlidingShow;
    
    BOOL canShowExifBtnForCurrentPhoto; // 只有记录的类型为Photo时，可以显示button
    BOOL showExifBtnIfPossible;         // 用户点击需要显示button
    BOOL areControlsHiddenBeforeExif;   // 点击exif按钮的时候，控件是否是隐藏的。
    
    CGRect _currentToolBarFrame;
    
    BOOL shouldAutoStartVideo;
    
}

@property (nonatomic, assign) NSUInteger currentPageIndex;

@property (nonatomic, retain) UIButton *loadOriginBtn;

// Private Properties
@property (nonatomic, retain) UIColor *previousNavBarTintColor;
@property (nonatomic, retain) UIBarButtonItem *previousViewControllerBackButton;
@property (nonatomic, retain) UIImage *navigationBarBackgroundImageDefault, *navigationBarBackgroundImageLandscapePhone;
@property (nonatomic, retain) UIActionSheet *actionsSheet;
@property (nonatomic, retain) MBProgressHUD *progressHUD;
@property (nonatomic, retain) UIView *commentViewContainer;
@property (nonatomic, retain) NSMutableDictionary * commentDataCacheDic;

@property (nonatomic, retain) TopSinglePixelLineView *progressBgView;
@property (nonatomic, retain) UIView *progressFrontView;
@property (nonatomic, retain) UIView *shortCaptionLabelBgView;
@property (nonatomic, retain) UILabel *shortCaptionLabel;

@property (nonatomic, retain) UILabel *recReasonLabel;



@property (nonatomic, assign) NSTimeInterval firstVideoOffset;



// Private Methods

// Layout
- (void)performLayout;

// Nav Bar Appearance
- (void)setNavBarAppearance:(BOOL)animated;
- (void)storePreviousNavBarAppearance;
- (void)restorePreviousNavBarAppearance:(BOOL)animated;

// Paging
- (void)tilePages;
- (BOOL)isDisplayingPageForIndex:(NSUInteger)index;
- (MWZoomingScrollView *)pageDisplayedAtIndex:(NSUInteger)index;
- (MWZoomingScrollView *)pageDisplayingPhoto:(id<MWPhoto>)photo;
- (MWZoomingScrollView *)dequeueRecycledPage;
- (void)configurePage:(MWZoomingScrollView *)page forIndex:(NSUInteger)index;
- (void)didStartViewingPageAtIndex:(NSUInteger)index;

// Frames
- (CGRect)frameForPagingScrollView;
- (CGRect)frameForPageAtIndex:(NSUInteger)index;
- (CGSize)contentSizeForPagingScrollView;
- (CGPoint)contentOffsetForPageAtIndex:(NSUInteger)index;
- (CGRect)frameForToolbarAtOrientation:(UIInterfaceOrientation)orientation;
- (CGRect)frameForCaptionView:(MWCaptionView *)captionView atIndex:(NSUInteger)index;

// Navigation
- (void)updateNavigation;
- (void)jumpToPageAtIndex:(NSUInteger)index;
- (void)jumpToPageAtIndex:(NSUInteger)index animated:(BOOL)animated;
- (void)gotoPreviousPage;
- (void)gotoNextPage;

// Controls
- (void)cancelControlHiding;
- (void)cancelSlideShow;
- (void)hideControlsAfterDelay;
- (void)setControlsHidden:(BOOL)hidden animated:(BOOL)animated permanent:(BOOL)permanent;
- (void)toggleControls;
- (BOOL)areControlsHidden;

// Data
- (NSUInteger)numberOfPhotos;
- (id<MWPhoto>)photoAtIndex:(NSUInteger)index;
- (UIImage *)imageForPhoto:(id<MWPhoto>)photo;

- (NSURL *)previewImageUrlForPhoto:(id<MWPhoto>)photo;

- (void)loadAdjacentPhotosIfNecessary:(id<MWPhoto>)photo;
- (void)releaseAllUnderlyingPhotos;

@end

// Handle depreciations and supress hide warnings
@interface UIApplication (DepreciationWarningSuppresion)
- (void)setStatusBarHidden:(BOOL)hidden animated:(BOOL)animated;
@end

// MWPhotoBrowser
@implementation MWPhotoBrowser

// Properties
@synthesize previousNavBarTintColor = _previousNavBarTintColor;
@synthesize navigationBarBackgroundImageDefault = _navigationBarBackgroundImageDefault,
navigationBarBackgroundImageLandscapePhone = _navigationBarBackgroundImageLandscapePhone;
@synthesize displayActionButton = _displayActionButton, actionsSheet = _actionsSheet, displaySlideShowButton = _displaySlideShowButton;
@synthesize progressHUD = _progressHUD;
@synthesize previousViewControllerBackButton = _previousViewControllerBackButton;

@synthesize commentViewContainer, commentDataCacheDic;

#pragma mark - NSObject



+ (UIImage*)imageNamed:(NSString*)imageName
{
    
    UIImage  *image = [UIImage  imageNamed:[NSString stringWithFormat:@"%@/%@",@"QWMWPhotoBrowser.bundle/",imageName]];
    if (image == nil)
    {
        image = [UIImage imageNamed:imageName];
    }
    return image;
}
- (id)init {
    if ((self = [super init])) {
        
        // Defaults
        //self.wantsFullScreenLayout = YES;
        
        if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
            [self setAutomaticallyAdjustsScrollViewInsets:NO];
        }
        
        self.hidesBottomBarWhenPushed = YES;
        _photoCount = NSNotFound;
        _currentPageIndex = 0;
        _performingLayout = NO; // Reset on view did appear
        _rotating = NO;
        _viewIsActive = NO;
        _visiblePages = [[NSMutableSet alloc] init];
        _recycledPages = [[NSMutableSet alloc] init];
        _photos = [[NSMutableArray alloc] init];
        _displayActionButton = NO;
        _displayEnterTripButton = NO;
        _displayLikeButton = NO;
        _displayCommentButton = NO;
        _displayCommentView = NO;
        _displaySlideShowButton = NO;
        _didSavePreviousStateOfNavBar = NO;
        
        _progressFrontView = [[UIView alloc] init];
        _progressBgView = [[TopSinglePixelLineView alloc] init];
        
        _shortCaptionLabel = [[UILabel alloc] init];
        _shortCaptionLabelBgView = [[UIView alloc] init];
        
        _displayLoadOriginalPhotoButton = NO;
        
        // Listen for MWPhoto notifications
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(handleMWPhotoLoadingDidEndNotification:)
                                                     name:MWPHOTO_LOADING_DID_END_NOTIFICATION
                                                   object:nil];

        
 
    }
    return self;
}

- (id)initWithDelegate:(id <MWPhotoBrowserDelegate>)delegate {
    if ((self = [self init])) {
        _delegate = [delegate retain];
    }
    return self;
}

- (id)initWithPhotos:(NSArray *)photosArray {
    if ((self = [self init])) {
        _depreciatedPhotoData = [photosArray retain];
    }
    return self;
}


- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [_previousNavBarTintColor release];
    [_navigationBarBackgroundImageDefault release];
    [_navigationBarBackgroundImageLandscapePhone release];
    [_previousViewControllerBackButton release];
    [_pagingScrollView release];
    [_visiblePages release];
    [_recycledPages release];
    [_toolbar release];
    [_actionButton release];
    [_commentButton release];
    [_likeButton release];
    [_depreciatedPhotoData release];
    [self releaseAllUnderlyingPhotos];
    [[SDImageCache sharedImageCache] clearMemory]; // clear memory
    [_photos release];
    [_progressHUD release];
    [_delegate release];
    [_actionsSheet release];
    self.commentViewContainer = nil;
    self.commentDataCacheDic = nil;
    
    [_progressBgView release];
    [_progressFrontView release];
    [_shortCaptionLabel release];
    [_shortCaptionLabelBgView release];
    
    [_loadOriginBtn release];
    [_recReasonLabel release];
    
    [super dealloc];
}



- (void)releaseAllUnderlyingPhotos {
    for (id p in _photos) { if (p != [NSNull null]) [p unloadUnderlyingImage]; } // Release photos
}

- (void)didReceiveMemoryWarning {
    
    // Release any cached data, images, etc that aren't in use.
    [self releaseAllUnderlyingPhotos];
    [_recycledPages removeAllObjects];
    
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
}

#pragma mark - View Loading

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    
    // View
    self.view.backgroundColor = [UIColor blackColor];
    [self.navigationController.navigationBar setTintColor:[UIColor whiteColor]];
    [self.navigationController setNavigationBarHidden:YES];
    // Setup paging scrolling view
    CGRect pagingScrollViewFrame = [self frameForPagingScrollView];
    _pagingScrollView = [[UIScrollView alloc] initWithFrame:pagingScrollViewFrame];
    _pagingScrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    _pagingScrollView.pagingEnabled = YES;
    _pagingScrollView.delegate = self;
    _pagingScrollView.showsHorizontalScrollIndicator = NO;
    _pagingScrollView.showsVerticalScrollIndicator = NO;
    _pagingScrollView.backgroundColor = [UIColor blackColor];
    _pagingScrollView.contentSize = [self contentSizeForPagingScrollView];
    [self.view addSubview:_pagingScrollView];
    
    // Toolbar

    //    if ([[UIToolbar class] respondsToSelector:@selector(appearance)]) {
    //        [_toolbar setBackgroundImage:[Utility getStrenchImageHasCache:@"nav_gallery_transparent"] forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];
    //    }
    //    else _toolbar.barStyle = UIBarStyleBlackTranslucent;


    // Toolbar
    // Toolbar
    _toolbar = [[UIToolbar alloc] initWithFrame:[self frameForToolbarAtOrientation:self.interfaceOrientation]];
    _toolbar.tintColor = SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7") ? [UIColor whiteColor] : nil;
    if ([_toolbar respondsToSelector:@selector(setBarTintColor:)]) {
        _toolbar.barTintColor = nil;
    }
    if ([[UIToolbar class] respondsToSelector:@selector(appearance)]) {
        [_toolbar setBackgroundImage:nil forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];
        [_toolbar setBackgroundImage:nil forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsLandscapePhone];
    }
    _toolbar.barStyle = UIBarStyleBlackTranslucent;
    _toolbar.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth;
    


    

    
    if (_displaySelectionButton) {
        _selectionBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        
        [_selectionBtn setFrame:CGRectMake(self.view.bounds.size.width - 85.0f, self.view.bounds.size.height - 85.0f, 85.0f, 85.0f)];
        _selectionBtn.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin;
        [_selectionBtn setContentHorizontalAlignment:UIControlContentHorizontalAlignmentRight];
        [_selectionBtn setImageEdgeInsets:UIEdgeInsetsMake(0.0f, -10.0f, 0.0f, 10.0f)];
        [_selectionBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
        [[_selectionBtn titleLabel] setFont:[UIFont systemFontOfSize:12]];
        [_selectionBtn setAdjustsImageWhenHighlighted:NO];
        [_selectionBtn setBackgroundColor:[UIColor clearColor]];
        [_selectionBtn setImage:[MWPhotoBrowser imageNamed:@"icon_unselect_60"] forState:UIControlStateNormal];
        [_selectionBtn setImage:[MWPhotoBrowser imageNamed:@"icon_select_60"] forState:UIControlStateHighlighted];
        [_selectionBtn setImage:[MWPhotoBrowser imageNamed:@"icon_select_60"] forState:UIControlStateSelected];
        [_selectionBtn addTarget:self action:@selector(toggleSelectionBtnPressed:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:_selectionBtn];
    }
    
    // Update
    [self reloadData];
    
    // Super
    [super viewDidLoad];
    

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(appWillResignActiveNotification:)
                                                 name:UIApplicationWillResignActiveNotification
                                               object:nil];
    
    
    if (_displayActionButton) {
        self.progressBgView.frame = CGRectMake(15.0f, self.view.bounds.size.height - 45.0f, self.view.bounds.size.width - 30.0f, 1.0f);
    } else {
        self.progressBgView.frame = CGRectMake(0.0f, self.view.bounds.size.height - 1.0f, self.view.bounds.size.width, 1.0f);
    }
    self.progressBgView.lineColor = [UIColor colorWithWhite:1.0f alpha:0.4];
    self.progressFrontView.frame = CGRectMake(0.0f, 0.0f, 0.0f, 1.0f);
    self.progressFrontView.backgroundColor = [UIColor colorWithWhite:1.0f alpha:0.8];;
    [self.view addSubview:self.progressBgView];
    [self.progressBgView addSubview:self.progressFrontView];
    
    //shortCaptionLabel
    self.shortCaptionLabelBgView = [[[UIView alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height - 34, self.view.bounds.size.width, 32)] autorelease];
    self.shortCaptionLabelBgView.backgroundColor = [UIColor clearColor];
    self.shortCaptionLabelBgView.alpha = 0;
    self.shortCaptionLabelBgView.userInteractionEnabled = NO;
    
    self.shortCaptionLabel.backgroundColor = [UIColor clearColor];
    _shortCaptionLabel.lineBreakMode = NSLineBreakByTruncatingTail;
    _shortCaptionLabel.numberOfLines = 2;
    _shortCaptionLabel.textColor = RGB(200, 200, 200);
    _shortCaptionLabel.font = [UIFont systemFontOfSize:14];
    self.shortCaptionLabel.frame = CGRectMake(5, 16, self.view.bounds.size.width, 16);
    
    [self.shortCaptionLabelBgView addSubview:self.shortCaptionLabel];
    [self.view addSubview:self.shortCaptionLabelBgView];
    
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(beginZoomingPhoto:) name:@"BEGIN__ZOOMINGPHOTO__" object:nil];
}



- (void)appWillResignActiveNotification:(NSNotification*)notify{
    

    
    [self setControlsHidden:NO animated:NO permanent:YES];
    
    [self cancelSlideShow];
    
    [self viewWillDisappear:NO];
}

-(void)beginZoomingPhoto:(NSNotification *)notification
{
    if (_loadOriginBtn && ![_loadOriginBtn isHidden]) {
        [self loadOriginalPhotoBtnPressed:nil];
    }
}

- (void)updateDoneSelectionBtnTitle
{
    NSInteger numberOfSelectedPhotos = 0;
    if ([_delegate respondsToSelector:@selector(numberOfSelectedPhotosInPhotoBrowser:)]) {
        numberOfSelectedPhotos = [_delegate numberOfSelectedPhotosInPhotoBrowser:self];
    }
    
    if (numberOfSelectedPhotos == 0) {
        [_selectionDoneBtn setTitle:NSLocalizedString(@"跳过", nil) forState:UIControlStateNormal];
    } else {
        NSString *titleStr = [NSString stringWithFormat:NSLocalizedString(@"下一步(%d)", nil), numberOfSelectedPhotos];
        [_selectionDoneBtn setTitle:titleStr forState:UIControlStateNormal];
    }
    
    CGSize btnSz = [_selectionDoneBtn sizeThatFits:CGSizeMake(self.view.bounds.size.width, 44.0f)];
    btnSz.width = MAX(64.0f, ceilf(btnSz.width));
    
    _selectionDoneBtn.frame = CGRectMake(CGRectGetMaxX(_selectionDoneBtn.frame) - btnSz.width,
                                         _selectionDoneBtn.frame.origin.y,
                                         btnSz.width,
                                         _selectionDoneBtn.frame.size.height);
    
    [[_selectionDoneBtn viewWithTag:10055] setFrame:CGRectInset(_selectionDoneBtn.bounds, 10.0f, 10.0f)];
}


- (UIImage*) getStrenchImageNoCache:(NSString*)imageName
{
    UIImage * img = [MWPhotoBrowser imageNamed:imageName];
    UIImage * imageS = [img stretchableImageWithLeftCapWidth:img.size.width/2 topCapHeight:img.size.height/2];
    return imageS;
}
- (void)performLayout {
    
    // Setup
    _performingLayout = YES;
    NSUInteger numberOfPhotos = [self numberOfPhotos];
    
    // Setup pages
    [_visiblePages removeAllObjects];
    [_recycledPages removeAllObjects];
    
    // Toolbar
    if (_displayActionButton || _displayLikeButton || _displayCommentButton) {
        [self.view addSubview:_toolbar];
        [self.view addSubview:self.shortCaptionLabelBgView];
    } else {
        [_toolbar removeFromSuperview];
    }
    
    [self.view addSubview:_recReasonLabel];
    
    if (numberOfPhotos > 1) {
        [self.view addSubview:self.progressBgView];
    } else {
        [self.progressBgView removeFromSuperview];
    }
    
    // Toolbar items & navigation
    NSMutableArray *items = [[NSMutableArray alloc] init];
    
    if (_displayLikeButton && _likeButton) [items addObject:_likeButton];
    
    if (_displayCommentButton && _commentButton) [items addObject:_commentButton];
    
    if (_displayActionButton) [items addObject:_actionButton];
    
    [_toolbar setItems:items];
    [items release];
    [self updateNavigation];
    
    UIImage * backImage = [MWPhotoBrowser imageNamed:@"bg_trip_btn_pic"];
    
 
    
    // Navigation buttons
    if ([self.navigationController.viewControllers objectAtIndex:0] == self) {
       
        _backBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        _backBtn.frame= CGRectMake(0, 20.0f, backImage.size.width + 20.0f, backImage.size.height + 20.0f);
        [_backBtn setContentEdgeInsets:UIEdgeInsetsMake(10, 10, 10, 10)];
        [_backBtn setImage:backImage forState:UIControlStateNormal];
        [_backBtn addTarget:self action:@selector(doneButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
        [_backBtn sizeToFit];
        
        [self.view addSubview:_backBtn];
        
        if (_displayDeleteButton) {
            UIImage *deleteImg = [MWPhotoBrowser imageNamed:@"icon_sticker_big_delete"];
            _deleteBtn = [UIButton buttonWithType:UIButtonTypeCustom];
            _deleteBtn.frame = CGRectMake(self.view.bounds.size.width - 10.0f - 40.0f,
                                          0, 40.0f, 44.0f);
            _deleteBtn.center = CGPointMake(_deleteBtn.center.x, _backBtn.center.y);
            [_deleteBtn setImage:deleteImg forState:UIControlStateNormal];
            [_deleteBtn setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin];
            [_deleteBtn addTarget:self
                           action:@selector(deletePhotoBtn:)
                 forControlEvents:UIControlEventTouchUpInside];
            
            [self.view addSubview:_deleteBtn];
            _loadOriginBtn.hidden = YES;
        } else if (_displaySelectionDoneButton) {
            _selectionDoneBtn = [UIButton buttonWithType:UIButtonTypeCustom];
            [_selectionDoneBtn.titleLabel setFont:[UIFont systemFontOfSize:17]];
            [_selectionDoneBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
            _selectionDoneBtn.frame = CGRectMake(self.view.bounds.size.width - 64.0f, 20.0f, 64.0f, 52.0f);
            _selectionDoneBtn.center = CGPointMake(_selectionDoneBtn.center.x, _backBtn.center.y);
            [_selectionDoneBtn setContentEdgeInsets:UIEdgeInsetsMake(0.0f, 20.0f, 0.0f, 20.0f)];
            [_selectionDoneBtn setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin];
            [_selectionDoneBtn addTarget:self
                                  action:@selector(doneSelectionBtnPressed:)
                        forControlEvents:UIControlEventTouchUpInside];
            
            UIImageView *bgImgView = [[UIImageView alloc] initWithFrame:CGRectInset(_selectionDoneBtn.bounds, 10.0f, 10.0f)];
            bgImgView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
            [bgImgView setImage:[self getStrenchImageNoCache:@"bg_trip_btn_gray"]];
            bgImgView.tag = 10055;
            [_selectionDoneBtn insertSubview:bgImgView belowSubview:_selectionDoneBtn.titleLabel];
            
            [self.view addSubview:_selectionDoneBtn];
            
            [self updateDoneSelectionBtnTitle];
            
            _loadOriginBtn.hidden = YES;
        } else {
            UIImage  *loadOriginImage = [MWPhotoBrowser imageNamed:@"nav_gallery_download_HDImage"];
            
            _loadOriginBtn = [[UIButton buttonWithType:UIButtonTypeCustom] retain];
            _loadOriginBtn.frame= CGRectMake(self.view.bounds.size.width - 10.0f - loadOriginImage.size.width, 30.0, loadOriginImage.size.width, loadOriginImage.size.height);
            [_loadOriginBtn setImage:loadOriginImage forState:UIControlStateNormal];
            [_loadOriginBtn addTarget:self action:@selector(loadOriginalPhotoBtnPressed:) forControlEvents:UIControlEventTouchUpInside];
            [_loadOriginBtn setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin];
            
            // 放大的时候自动下载，不显示按钮。这个按钮现在只是为了保留原来的逻辑，不会显示。
                //[self.view addSubview:_loadOriginBtn];
            
            if (_displayLoadOriginalPhotoButton) {
                _loadOriginBtn.hidden = NO;
            } else {
                _loadOriginBtn.hidden = YES;
            }
            _deleteBtn.hidden = YES;
        }
    } else {
        // We're not first so show back button
        UIViewController *previousViewController = [self.navigationController.viewControllers objectAtIndex:self.navigationController.viewControllers.count-2];
        NSString *backButtonTitle = previousViewController.navigationItem.backBarButtonItem ? previousViewController.navigationItem.backBarButtonItem.title : previousViewController.title;
        UIBarButtonItem *newBackButton = [[[UIBarButtonItem alloc] initWithTitle:backButtonTitle style:UIBarButtonItemStylePlain target:nil action:nil] autorelease];
        // Appearance
        if ([UIBarButtonItem respondsToSelector:@selector(appearance)]) {
            [newBackButton setBackButtonBackgroundImage:nil forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
            [newBackButton setBackButtonBackgroundImage:nil forState:UIControlStateNormal barMetrics:UIBarMetricsLandscapePhone];
            [newBackButton setBackButtonBackgroundImage:nil forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault];
            [newBackButton setBackButtonBackgroundImage:nil forState:UIControlStateHighlighted barMetrics:UIBarMetricsLandscapePhone];
            [newBackButton setTitleTextAttributes:[NSDictionary dictionary] forState:UIControlStateNormal];
            [newBackButton setTitleTextAttributes:[NSDictionary dictionary] forState:UIControlStateHighlighted];
        }
        self.previousViewControllerBackButton = previousViewController.navigationItem.backBarButtonItem; // remember previous
        previousViewController.navigationItem.backBarButtonItem = newBackButton;
    }
    
    // Content offset
    _pagingScrollView.contentOffset = [self contentOffsetForPageAtIndex:_currentPageIndex];
    [self tilePages];
    _performingLayout = NO;
}

// Release any retained subviews of the main view.
- (void)viewDidUnload {
    self.currentPageIndex = 0;
    [_pagingScrollView release], _pagingScrollView = nil;
    [_visiblePages release], _visiblePages = nil;
    [_recycledPages release], _recycledPages = nil;
    [_toolbar release], _toolbar = nil;
    [_commentButton release], _commentButton = nil;
    [_likeButton release], _likeButton= nil;
    self.progressHUD = nil;
    self.commentDataCacheDic = nil;
    self.commentViewContainer = nil;
    [super viewDidUnload];
}

#pragma mark - Appearance

- (void)viewWillAppear:(BOOL)animated {
    
    
    // Super
    [super viewWillAppear:animated];
    
    [self.navigationController setNavigationBarHidden:YES animated:animated];
    

    
    // Status bar
  
    _previousStatusBarStyle = [[UIApplication sharedApplication] statusBarStyle];
    
    // Navigation bar appearance
    if (!_viewIsActive && [self.navigationController.viewControllers objectAtIndex:0] != self) {
        [self storePreviousNavBarAppearance];
    }
    [self setNavBarAppearance:animated];
    
    // Update UI
    [self hideControlsAfterDelay];
    

}

- (void)viewWillDisappear:(BOOL)animated {

    // Check that we're being popped for good
    if ([self.navigationController.viewControllers objectAtIndex:0] != self &&
        ![self.navigationController.viewControllers containsObject:self]) {
        
        // State
        _viewIsActive = NO;
        
        // Bar state / appearance
        [self restorePreviousNavBarAppearance:animated];
        
    }
    
    if (self.navigationController.viewControllers.count > 1) {
        [self.navigationController setNavigationBarHidden:NO animated:animated];
    }
    
    
    // Controls
    [self.navigationController.navigationBar.layer removeAllAnimations]; // Stop all animations on nav bar
    [NSObject cancelPreviousPerformRequestsWithTarget:self]; // Cancel any pending toggles from taps
    [self setControlsHidden:NO animated:NO permanent:YES];
    
//    // Status bar
//    if (self.wantsFullScreenLayout && UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
//        [[UIApplication sharedApplication] setStatusBarStyle:_previousStatusBarStyle animated:animated];
//    }
    
    // Super
    [super viewWillDisappear:animated];
    
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    _viewIsActive = YES;
}

#pragma mark - Nav Bar Appearance

- (void)setNavBarAppearance:(BOOL)animated {


    self.navigationController.navigationBar.tintColor = [UIColor whiteColor];
    self.navigationController.navigationBar.barStyle = UIBarStyleBlackTranslucent;
    if ([[UINavigationBar class] respondsToSelector:@selector(appearance)]) {
        //        [self.navigationController.navigationBar setBackgroundImage:barBgImg forBarMetrics:UIBarMetricsDefault];
        //        [self.navigationController.navigationBar setBackgroundImage:barBgImg forBarMetrics:UIBarMetricsLandscapePhone];
        //        [self.navigationController.navigationBar setBackgroundColor:[UIColor clearColor]];
        
        NSDictionary *navbarTitleTextAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
                                                   [UIFont systemFontOfSize:17], NSFontAttributeName,
                                                   [UIColor whiteColor],NSForegroundColorAttributeName,
                                                   [UIColor clearColor], NSShadowAttributeName,
                                                   [NSValue valueWithUIOffset:UIOffsetMake(0, 0)], NSBaselineOffsetAttributeName, nil];
        self.navigationController.navigationBar.titleTextAttributes =  navbarTitleTextAttributes;
        //        [[UINavigationBar appearance] setTitleTextAttributes:navbarTitleTextAttributes];
        
    }

    if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
        //remove 1px inner shadow
        for (UIView *view in self.navigationController.navigationBar.subviews) {
            for (UIView *view2 in view.subviews) {
                if ([view2 isKindOfClass:[UIImageView class]]) {
                    [view2 removeFromSuperview];
                }
            }
        }
        
    }
}

- (void)storePreviousNavBarAppearance {
    _didSavePreviousStateOfNavBar = YES;
    self.previousNavBarTintColor = self.navigationController.navigationBar.tintColor;
    _previousNavBarStyle = self.navigationController.navigationBar.barStyle;
    if ([[UINavigationBar class] respondsToSelector:@selector(appearance)]) {
        self.navigationBarBackgroundImageDefault = [self.navigationController.navigationBar backgroundImageForBarMetrics:UIBarMetricsDefault];
        self.navigationBarBackgroundImageLandscapePhone = [self.navigationController.navigationBar backgroundImageForBarMetrics:UIBarMetricsLandscapePhone];
    }
}

- (void)restorePreviousNavBarAppearance:(BOOL)animated {
    if (_didSavePreviousStateOfNavBar) {
        self.navigationController.navigationBar.tintColor = _previousNavBarTintColor;
        self.navigationController.navigationBar.barStyle = _previousNavBarStyle;
        if ([[UINavigationBar class] respondsToSelector:@selector(appearance)]) {
            [self.navigationController.navigationBar setBackgroundImage:_navigationBarBackgroundImageDefault forBarMetrics:UIBarMetricsDefault];
            [self.navigationController.navigationBar setBackgroundImage:_navigationBarBackgroundImageLandscapePhone forBarMetrics:UIBarMetricsLandscapePhone];
        }
        // Restore back button if we need to
        if (_previousViewControllerBackButton) {
            UIViewController *previousViewController = [self.navigationController topViewController]; // We've disappeared so previous is now top
            previousViewController.navigationItem.backBarButtonItem = _previousViewControllerBackButton;
            self.previousViewControllerBackButton = nil;
        }
    }
}

#pragma mark - Layout

- (void)viewWillLayoutSubviews {
    
    // Super
    if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"5")) [super viewWillLayoutSubviews];
    
    // Flag
    _performingLayout = YES;
    
    // Toolbar
    _toolbar.frame = [self frameForToolbarAtOrientation:self.interfaceOrientation];
    
    _recReasonLabel.frame = CGRectMake(220.0f,
                                       self.view.bounds.size.height - _toolbar.frame.size.height,
                                       self.view.bounds.size.width - 235.0f,
                                       _toolbar.frame.size.height);
    
    //commentViewContainer add by eric
    self.commentViewContainer.frame = [self frameForCommentViewContain:self.interfaceOrientation];
    
    // Remember index
    NSUInteger indexPriorToLayout = _currentPageIndex;
    
    // Get paging scroll view frame to determine if anything needs changing
    CGRect pagingScrollViewFrame = [self frameForPagingScrollView];
    
    if (_displayActionButton) {
        self.progressBgView.frame = CGRectMake(15.0f, self.view.bounds.size.height - _toolbar.frame.size.height, self.view.bounds.size.width - 30.0f, 1.0f);
    } else {
        self.progressBgView.frame = CGRectMake(0.0f, self.view.bounds.size.height - 1.0f, self.view.bounds.size.width, 1.0f);
    }
    
    if ([self numberOfPhotos] > 1) {
        self.progressFrontView.frame = CGRectMake(0, 0, self.progressBgView.bounds.size.width * (_currentPageIndex + 1)/[self numberOfPhotos], 1.0f);
        self.progressBgView.hidden = NO;
    } else {
        self.progressFrontView.frame = CGRectMake(0, 0, 0, 1.0f);
        self.progressBgView.hidden = YES;
    }
    
    //    _shortCaptionLabel
    self.shortCaptionLabelBgView.frame = CGRectMake(0, self.view.bounds.size.height - 34, self.view.bounds.size.width, 32);
    NSString *shortCaptionTxt = self.shortCaptionLabel.text;
    if([shortCaptionTxt length] > 0){
        CGSize labelSize = [shortCaptionTxt sizeWithFont:_shortCaptionLabel.font
                                       constrainedToSize:CGSizeMake(self.view.bounds.size.width, 99999.0f)
                                           lineBreakMode:NSLineBreakByTruncatingTail];
        CGFloat lineHeight = self.shortCaptionLabel.font.lineHeight;
        NSUInteger linesInLabel = floor(labelSize.height/lineHeight);
        if (linesInLabel > 1) {
            self.shortCaptionLabel.frame = CGRectMake(5, 0, self.view.bounds.size.width - 10, 32.0f);
        }else{
            self.shortCaptionLabel.frame = CGRectMake(5, 16.0f, self.view.bounds.size.width - 10, 16.0f);
        }
    }else{
        self.shortCaptionLabel.frame = CGRectMake(5, 16.0f, self.view.bounds.size.width - 10, 0);
    }
    
    
    // Frame needs changing
    _pagingScrollView.frame = pagingScrollViewFrame;
    
    // Recalculate contentSize based on current orientation
    _pagingScrollView.contentSize = [self contentSizeForPagingScrollView];
    
    // Adjust frames and configuration of each visible page
    for (MWZoomingScrollView *page in [[_visiblePages copy] autorelease]) {
        NSUInteger index = PAGE_INDEX(page);
        page.frame = [self frameForPageAtIndex:index];
        page.captionView.frame = [self frameForCaptionView:page.captionView atIndex:index];
        [page setMaxMinZoomScalesForCurrentBounds];
        
        [page layoutIfNeeded];
    }
    
    // Adjust exifInfoView frames and configuration of each visible page
    for (MWZoomingScrollView *page in [[_visiblePages copy] autorelease]) {
        NSUInteger index = PAGE_INDEX(page);
        page.frame = [self frameForPageAtIndex:index];
        page.gradMaskImgView.frame = [self frameForGradientBackgroundViewAtIndex:index];
    }
    
    // Adjust contentOffset to preserve page location based on values collected prior to location
    if (!_pagingScrollView.isDecelerating) {
        _pagingScrollView.contentOffset = [self contentOffsetForPageAtIndex:indexPriorToLayout];
    }
    
    [self didStartViewingPageAtIndex:_currentPageIndex]; // initial
    
    // Reset
    self.currentPageIndex = indexPriorToLayout;
    _performingLayout = NO;
}

#pragma mark - Rotation
// support iOS6 rotate
- (BOOL)shouldAutorotate NS_AVAILABLE_IOS(6_0){
    return YES;
}

//- (UIInterfaceOrientationMask)supportedInterfaceOrientations NS_AVAILABLE_IOS(6_0){
//    return UIInterfaceOrientationMaskAllButUpsideDown;
//}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
    return YES;
}

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    
    // Remember page index before rotation
    _pageIndexBeforeRotation = _currentPageIndex;
    _rotating = YES;
    
}

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    
    // Perform layout
    self.currentPageIndex = _pageIndexBeforeRotation;
    
    // Layout manually (iOS < 5)
    if (SYSTEM_VERSION_LESS_THAN(@"5")) [self viewWillLayoutSubviews];
    
    // Delay control holding
    [self hideControlsAfterDelay];
    
}

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
    _rotating = NO;
}

#pragma mark - Data

- (void)reloadData {
    
    // Reset
    _photoCount = NSNotFound;
    
    // Get data
    NSUInteger numberOfPhotos = [self numberOfPhotos];
    [self releaseAllUnderlyingPhotos];
    [_photos removeAllObjects];
    for (int i = 0; i < numberOfPhotos; i++) [_photos addObject:[NSNull null]];
    
    // Update
    [self performLayout];
    
    // Layout
    if (SYSTEM_VERSION_LESS_THAN(@"5")) [self viewWillLayoutSubviews];
    else [self.view setNeedsLayout];
    
}

- (NSUInteger)numberOfPhotos {
    if (_photoCount == NSNotFound) {
        if ([_delegate respondsToSelector:@selector(numberOfPhotosInPhotoBrowser:)]) {
            _photoCount = [_delegate numberOfPhotosInPhotoBrowser:self];
        } else if (_depreciatedPhotoData) {
            _photoCount = _depreciatedPhotoData.count;
        }
    }
    if (_photoCount == NSNotFound) _photoCount = 0;
    return _photoCount;
}

- (id<MWPhoto>)photoAtIndex:(NSUInteger)index {
    id <MWPhoto> photo = nil;
    if (index < _photos.count) {
        if ([_photos objectAtIndex:index] == [NSNull null]) {
            if ([_delegate respondsToSelector:@selector(photoBrowser:photoAtIndex:)]) {
                photo = [_delegate photoBrowser:self photoAtIndex:index];
            } else if (_depreciatedPhotoData && index < _depreciatedPhotoData.count) {
                photo = [_depreciatedPhotoData objectAtIndex:index];
            }
            if (photo) [_photos replaceObjectAtIndex:index withObject:photo];
        } else {
            photo = [_photos objectAtIndex:index];
        }
    }
    return photo;
}


- (MWCaptionView *)captionViewForPhotoAtIndex:(NSUInteger)index {
    MWCaptionView *captionView = nil;
    if ([_delegate respondsToSelector:@selector(photoBrowser:captionViewForPhotoAtIndex:)]) {
        captionView = [_delegate photoBrowser:self captionViewForPhotoAtIndex:index];
    } else {
        id <MWPhoto> photo = [self photoAtIndex:index];
        if ([photo respondsToSelector:@selector(caption)]) {
            if ([photo caption]) captionView = [[[MWCaptionView alloc] initWithPhoto:photo] autorelease];
        }
    }
    captionView.alpha = [self areControlsHidden] ? 0 : 1; // Initial alpha
    return captionView;
}



- (UIImage *)imageForPhoto:(id<MWPhoto>)photo {
    if (photo) {
        // Get image or obtain in background
        // FIXZHY: what if underlyingImage is smaller than expected.
        if ([photo underlyingImage]) {
            return [photo underlyingImage];
        } else {
            [photo loadUnderlyingImageAndNotifyWithHDImage:NO];
        }
    }
    return nil;
}

- (NSURL *)previewImageUrlForPhoto:(id<MWPhoto>)photo {
    if ([photo previewPhotoURL]) {
        return [photo previewPhotoURL];
    }
    return nil;
}

- (void)loadAdjacentPhotosIfNecessary:(id<MWPhoto>)photo {
    MWZoomingScrollView *page = [self pageDisplayingPhoto:photo];
    if (page) {
        // If page is current page then initiate loading of previous and next pages
        NSUInteger pageIndex = PAGE_INDEX(page);
        if (_currentPageIndex == pageIndex) {
            if (pageIndex > 0) {
                // Preload index - 1
                id <MWPhoto> photo = [self photoAtIndex:pageIndex-1];
                if (![photo underlyingImage]) {
                    [photo loadUnderlyingImageAndNotifyWithHDImage:NO];
                    MWLog(@"Pre-loading image at index %i", pageIndex-1);
                }
            }
            if (pageIndex + 1 < [self numberOfPhotos]) {
                // Preload index + 1
                id <MWPhoto> photo = [self photoAtIndex:pageIndex+1];
                if (![photo underlyingImage]) {
                    [photo loadUnderlyingImageAndNotifyWithHDImage:NO];
                    MWLog(@"Pre-loading image at index %i", pageIndex+1);
                }
            }
        }
    }
}

#pragma mark - MWPhoto Loading Notification

- (void)handleMWPhotoLoadingDidEndNotification:(NSNotification *)notification {
    MWPhoto* photo = (MWPhoto*)[notification object];
    MWZoomingScrollView *page = [self pageDisplayingPhoto:photo];
    if (page) {
        if ([photo underlyingImage]) {
            // Successful load
            //modify by eric
            if(photo.underlyingImage && photo.currentPhotoType > MWPhotoMini){
                [page chagePreviewImgToBig];
            } else if (photo.underlyingImage && photo.currentPhotoType == MWPhotoOriginal) {
                [page chagePreviewImgToBig];
            }else {
                [page displayImage];
                [self loadAdjacentPhotosIfNecessary:photo];
            }
            
        } else {
            // Failed to load
            [page displayImageFailure];
        }
    }
}

#pragma mark - Paging

- (void)tilePages {
    
    // Calculate which pages should be visible
    // Ignore padding as paging bounces encroach on that
    // and lead to false page loads
    CGRect visibleBounds = _pagingScrollView.bounds;
    int iFirstIndex = (int)floorf((CGRectGetMinX(visibleBounds)+PADDING*2) / CGRectGetWidth(visibleBounds));
    int iLastIndex  = (int)floorf((CGRectGetMaxX(visibleBounds)-PADDING*2-1) / CGRectGetWidth(visibleBounds));
    if (iFirstIndex < 0) iFirstIndex = 0;
    if (iFirstIndex + 1 > [self numberOfPhotos]) iFirstIndex = (int)[self numberOfPhotos] - 1;
    if (iLastIndex < 0) iLastIndex = 0;
    if (iLastIndex + 1 > [self numberOfPhotos]) iLastIndex = (int)[self numberOfPhotos] - 1;
    
    // Recycle no longer needed pages
    NSInteger pageIndex;
    for (MWZoomingScrollView *page in _visiblePages) {
        pageIndex = PAGE_INDEX(page);
        if (pageIndex < (NSUInteger)iFirstIndex || pageIndex > (NSUInteger)iLastIndex) {
            [_recycledPages addObject:page];
            [page prepareForReuse];
            [page removeFromSuperview];
            MWLog(@"Removed page at index %i", PAGE_INDEX(page));
        }
    }
    [_visiblePages minusSet:_recycledPages];
    while (_recycledPages.count > 2) // Only keep 2 recycled pages
        [_recycledPages removeObject:[_recycledPages anyObject]];
    
    // Add missing pages
    for (NSUInteger index = (NSUInteger)iFirstIndex; index <= (NSUInteger)iLastIndex; index++) {
        if (![self isDisplayingPageForIndex:index]) {
            
            // Add new page
            MWZoomingScrollView *page = [self dequeueRecycledPage];
            if (!page) {
                page = [[[MWZoomingScrollView alloc] initWithPhotoBrowser:self] autorelease];
            }
            [self configurePage:page forIndex:index];
            [_visiblePages addObject:page];
            [_pagingScrollView addSubview:page];
            MWLog(@"Added page at index %i", index);
    
            // Add caption
            MWCaptionView *captionView = [self captionViewForPhotoAtIndex:index];
            captionView.frame = [self frameForCaptionView:captionView atIndex:index];
            [_pagingScrollView addSubview:captionView];
            page.captionView = captionView;
            

        }
    }
}

- (BOOL)isDisplayingPageForIndex:(NSUInteger)index {
    for (MWZoomingScrollView *page in _visiblePages)
        if (PAGE_INDEX(page) == index) return YES;
    return NO;
}

- (MWZoomingScrollView *)pageDisplayedAtIndex:(NSUInteger)index {
    MWZoomingScrollView *thePage = nil;
    for (MWZoomingScrollView *page in [[_visiblePages copy] autorelease]) {
        if (PAGE_INDEX(page) == index) {
            thePage = page; break;
        }
    }
    return thePage;
}

- (MWZoomingScrollView *)pageDisplayingPhoto:(id<MWPhoto>)photo {
    MWZoomingScrollView *thePage = nil;
    for (MWZoomingScrollView *page in _visiblePages) {
        if (page.photo == photo) {
            thePage = page; break;
        }
    }
    return thePage;
}

- (void)configurePage:(MWZoomingScrollView *)page forIndex:(NSUInteger)index {
    page.frame = [self frameForPageAtIndex:index];
    page.tag = PAGE_INDEX_TAG_OFFSET + index;
    page.photo = [self photoAtIndex:index];
}

- (MWZoomingScrollView *)dequeueRecycledPage {
    MWZoomingScrollView *page = [_recycledPages anyObject];
    if (page) {
        [[page retain] autorelease];
        [_recycledPages removeObject:page];
    }
    return page;
}

// Handle page changes
- (void)didStartViewingPageAtIndex:(NSUInteger)index {
 
    // Release images further away than +/-1
    NSUInteger i;
    if (index > 0) {
        // Release anything < index - 1
        for (i = 0; i + 1 < index; i++) {
            id photo = [_photos objectAtIndex:i];
            if (photo != [NSNull null]) {
                [photo unloadUnderlyingImage];
                [_photos replaceObjectAtIndex:i withObject:[NSNull null]];
                MWLog(@"Released underlying image at index %i", i);
            }
        }
    }
    if (index < [self numberOfPhotos] - 1) {
        // Release anything > index + 1
        for (i = index + 2; i < _photos.count; i++) {
            id photo = [_photos objectAtIndex:i];
            if (photo != [NSNull null]) {
                [photo unloadUnderlyingImage];
                [_photos replaceObjectAtIndex:i withObject:[NSNull null]];
                MWLog(@"Released underlying image at index %i", i);
            }
        }
    }
    
    // Load adjacent images if needed and the photo is already
    // loaded. Also called after photo has been loaded in background
    id <MWPhoto> currentPhoto = [self photoAtIndex:index];
    if ([currentPhoto underlyingImage]) {
        // photo loaded so load ajacent now
        [self loadAdjacentPhotosIfNecessary:currentPhoto];
    }
}

#pragma mark - Frame Calculations

- (CGRect)frameForPagingScrollView {
    CGRect frame = self.view.bounds;// [[UIScreen mainScreen] bounds];
    frame.origin.x -= PADDING;
    frame.size.width += (2 * PADDING);
    return frame;
}

- (CGRect)frameForPageAtIndex:(NSUInteger)index {
    // We have to use our paging scroll view's bounds, not frame, to calculate the page placement. When the device is in
    // landscape orientation, the frame will still be in portrait because the pagingScrollView is the root view controller's
    // view, so its frame is in window coordinate space, which is never rotated. Its bounds, however, will be in landscape
    // because it has a rotation transform applied.
    CGRect bounds = _pagingScrollView.bounds;
    CGRect pageFrame = bounds;
    pageFrame.size.width -= (2 * PADDING);
    pageFrame.origin.x = (bounds.size.width * index) + PADDING;
    return pageFrame;
}

- (CGSize)contentSizeForPagingScrollView {
    // We have to use the paging scroll view's bounds to calculate the contentSize, for the same reason outlined above.
    CGRect bounds = _pagingScrollView.bounds;
    return CGSizeMake(bounds.size.width * [self numberOfPhotos], bounds.size.height);
}

- (CGPoint)contentOffsetForPageAtIndex:(NSUInteger)index {
    CGFloat pageWidth = _pagingScrollView.bounds.size.width;
    CGFloat newOffset = index * pageWidth;
    return CGPointMake(newOffset, 0);
}

- (CGRect)frameForToolbarAtOrientation:(UIInterfaceOrientation)orientation {
    CGFloat height = 44;
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone &&
        UIInterfaceOrientationIsLandscape(orientation)) height = 32;
    
    _currentToolBarFrame = CGRectMake(0, self.view.bounds.size.height - height, self.view.bounds.size.width, height);
    return _currentToolBarFrame;
}

- (CGRect)frameForCommentViewContain:(UIInterfaceOrientation)orientation
{
    CGFloat navHeight = 44;
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone &&
        UIInterfaceOrientationIsLandscape(orientation)) navHeight = 32;
    
    CGFloat height = [UIScreen mainScreen].bounds.size.height - navHeight  -20;
    
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone &&
        UIInterfaceOrientationIsLandscape(orientation)) height = 320 - navHeight - 20;
    
    return CGRectMake(0, self.view.bounds.size.height, self.view.bounds.size.width, height);
}

- (CGRect)frameForCaptionView:(MWCaptionView *)captionView atIndex:(NSUInteger)index {
    CGRect pageFrame = [self frameForPageAtIndex:index];
    CGFloat toolBarHeight = (_toolbar.superview ? _toolbar.frame.size.height : 0);
    
    //    captionView.frame = CGRectMake(0, 0, pageFrame.size.width, 44); // set initial frame
    //    CGSize captionSize = [captionView sizeThatFits:CGSizeMake(pageFrame.size.width,
    //                                                              pageFrame.size.height - toolBarHeight)];
    //    CGRect captionFrame = CGRectMake(pageFrame.origin.x,
    //                                     pageFrame.size.height - captionSize.height - toolBarHeight,
    //                                     pageFrame.size.width,
    //                                     captionSize.height + toolBarHeight);
    

    return pageFrame;
}



- (CGRect)frameForGradientBackgroundViewAtIndex:(NSUInteger)index {
    CGRect pageFrame = [self frameForPageAtIndex:index];
    CGRect captionFrame = CGRectMake(pageFrame.origin.x, pageFrame.size.height - 195.0f,
                                     pageFrame.size.width, 195.0f);
    return captionFrame;
}
#pragma mark - UIScrollView Delegate

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    
    if (!(scrollView.isTracking || scrollView.isDragging)) {
        MWLog(@"is programmatic scroll");
    }else if(isSlidingShow){// touch the screen
        [self cancelSlideShow];
    }
    
    // Checks
    if (!_viewIsActive || _performingLayout || _rotating) return;
    
    // Tile pages
    [self tilePages];
    
    // Calculate current page
    CGRect visibleBounds = _pagingScrollView.bounds;
    int index = (int)(floorf(CGRectGetMidX(visibleBounds) / CGRectGetWidth(visibleBounds)));
    if (index < 0) index = 0;
    if (index + 1 > [self numberOfPhotos]) index = (int)[self numberOfPhotos] - 1;
    NSUInteger previousCurrentPage = _currentPageIndex;
    self.currentPageIndex = index;
    if (_currentPageIndex != previousCurrentPage) {
        [self didStartViewingPageAtIndex:index];
        [self setDisplayLoadOriginalPhotoButton:NO];
    }
}

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    // Hide controls when dragging begins
    //    if (self.isEXIFViewHidden == NO){
    //        self.isEXIFViewHidden = YES;
    //        [self setExifViewHidden:self.isEXIFViewHidden];
    //    }
    //	[self setControlsHidden:[self areControlsHidden] animated:YES permanent:YES];
}

//add by eric begin
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
    // Update nav when page changes
    [self updateNavigation];
    
    if (!decelerate) {
        if (!CGPointEqualToPoint(scrollView.contentOffset, [self contentOffsetForPageAtIndex:_currentPageIndex])) {
            _pagingScrollView.contentOffset = [self contentOffsetForPageAtIndex:_currentPageIndex];
        }
    }

}

-(void)loadMoreSpotPicsSuccess:(BOOL)isSliding
{
    [self showProgressHUDCompleteMessage:nil];
}





//add by eric end


- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    // Update nav when page changes
    [self updateNavigation];
    
    if (!CGPointEqualToPoint(scrollView.contentOffset, [self contentOffsetForPageAtIndex:_currentPageIndex])) {
        _pagingScrollView.contentOffset = [self contentOffsetForPageAtIndex:_currentPageIndex];
    }
}

#pragma mark - Navigation

- (void)updateNavigation {
    
    MWPhoto* photo = (MWPhoto* )[self photoAtIndex:_currentPageIndex];
    
    if (photo.isSelected) {
        [_selectionBtn setImage:[MWPhotoBrowser imageNamed:@"icon_select_60"] forState:UIControlStateNormal];
    } else {
        [_selectionBtn setImage:[MWPhotoBrowser imageNamed:@"icon_unselect_60"] forState:UIControlStateNormal];
    }
    _backBtn.enabled = YES;
    

    
    // progress
    if ([self numberOfPhotos] > 1) {
        self.progressFrontView.frame = CGRectMake(0, 0, self.progressBgView.bounds.size.width * (_currentPageIndex + 1) / [self numberOfPhotos], 1.0f);
        self.progressBgView.hidden = NO;
    } else {
        self.progressFrontView.frame = CGRectMake(0, 0, 0, 1.0f);
        self.progressBgView.hidden = YES;
    }
    
    //    _shortCaptionLabel
    
    NSString *shortCaptionTxt = photo.caption;
    self.shortCaptionLabel.text = shortCaptionTxt;
    if(photo.caption && [photo.caption length] > 0){
        CGSize labelSize = [shortCaptionTxt sizeWithFont:_shortCaptionLabel.font
                                       constrainedToSize:CGSizeMake(self.view.bounds.size.width, 99999.0f)
                                           lineBreakMode:NSLineBreakByTruncatingTail];
        CGFloat lineHeight = self.shortCaptionLabel.font.lineHeight;
        NSUInteger linesInLabel = floor(labelSize.height/lineHeight);
        if (linesInLabel > 1) {
            self.shortCaptionLabel.frame = CGRectMake(5, 0.0f , self.view.bounds.size.width - 10, 32.0f);
        }else{
            self.shortCaptionLabel.frame = CGRectMake(5, 16.0f, self.view.bounds.size.width - 10, 16.0f);
        }
    }else{
        self.shortCaptionLabel.frame = CGRectMake(5, 16.0f, self.view.bounds.size.width - 10, 0);
    }
    
    
    _actionButton.enabled = [self isActionButtonEnabledAtIndex:_currentPageIndex];
}


- (BOOL)isActionButtonEnabledAtIndex:(NSInteger)index
{
    
    if (_delegate && [_delegate respondsToSelector:@selector(photoBrowser:isActionButtonEnabledAtIndex:)]) {
        return [_delegate photoBrowser:self isActionButtonEnabledAtIndex:index];
    }
    return YES;
}

- (void)jumpToPageAtIndex:(NSUInteger)index {
    
    // Change page
    if (index < [self numberOfPhotos]) {
        CGRect pageFrame = [self frameForPageAtIndex:index];
        _pagingScrollView.contentOffset = CGPointMake(pageFrame.origin.x - PADDING, 0);
        [self updateNavigation];
    }
    
    [self setDisplayLoadOriginalPhotoButton:NO];
    // Update timer to give more time
    [self hideControlsAfterDelay];
}

- (void)jumpToPageAtIndex:(NSUInteger)index animated:(BOOL)animated{
    
    // Change page
    if (index < [self numberOfPhotos]) {
        CGRect pageFrame = [self frameForPageAtIndex:index];
        [_pagingScrollView setContentOffset:CGPointMake(pageFrame.origin.x - PADDING, 0) animated:animated];
        [self performSelector:@selector(updateNavigation) withObject:nil afterDelay:0.3];
        
    } else {

        
        [self setControlsHidden:NO animated:NO permanent:YES];
        [self cancelSlideShow];
    }
    
    [self setDisplayLoadOriginalPhotoButton:NO];
    // Update timer to give more time
    //	[self hideControlsAfterDelay];
    
}

- (void)gotoPreviousPage { [self jumpToPageAtIndex:_currentPageIndex-1]; }
- (void)gotoNextPage { [self jumpToPageAtIndex:_currentPageIndex+1]; }







#pragma mark - Control Hiding / Showing

// If permanent then we don't set timers to hide again
- (void)setControlsHidden:(BOOL)hidden animated:(BOOL)animated permanent:(BOOL)permanent {
    
    // Cancel any timers
    [self cancelControlHiding];


    // Captions
    NSMutableSet *visPages = [[[NSMutableSet alloc] initWithCapacity:_visiblePages.count] autorelease];
    for (MWZoomingScrollView *page in _visiblePages) {
        [visPages addObject:page];
    }
    

    
    // Animate
    if (animated) {
        [UIView beginAnimations:nil context:nil];
        [UIView setAnimationDuration:0.35];
    }
    CGFloat alpha = hidden ? 0 : 1;
    [_toolbar setAlpha:alpha];
    [_backBtn setAlpha:alpha];
    [_loadOriginBtn setAlpha:alpha];
    [_recReasonLabel setAlpha:alpha];
    
    for (MWZoomingScrollView *page in visPages) {
        page.captionView.alpha = alpha;
    }
    

    
    _progressBgView.alpha = alpha;
    _selectionBtn.alpha = alpha;
    _selectionDoneBtn.alpha = alpha;
    


    self.shortCaptionLabelBgView.alpha = 0;
    
    if (animated) [UIView commitAnimations];
    
   [[UIApplication sharedApplication] setStatusBarHidden:hidden];
    
    // Control hiding timer
    // Will cancel existing timer but only begin hiding if
    // they are visible
    if (!permanent) [self hideControlsAfterDelay];
    
}

- (void)cancelControlHiding {
    // If a timer exists then cancel and release
    if (_controlVisibilityTimer) {
        [_controlVisibilityTimer invalidate];
        [_controlVisibilityTimer release];
        _controlVisibilityTimer = nil;
    }
}

- (void)cancelSlideShow {
    // If a timer exists then cancel and release
    if (_controlSlideShowTimer) {
        [_controlSlideShowTimer invalidate];
        [_controlSlideShowTimer release];
        _controlSlideShowTimer = nil;
    }
    isSlidingShow = NO;
}

// Enable/disable control visiblity timer
- (void)hideControlsAfterDelay {
    if (![self areControlsHidden]) {
        [self cancelControlHiding];
        //		_controlVisibilityTimer = [[NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(hideControls) userInfo:nil repeats:NO] retain];
    }
}

- (BOOL)areControlsHidden { return (_toolbar.alpha == 0); /* [UIApplication sharedApplication].isStatusBarHidden; */ }
- (void)hideControls {
    [self setControlsHidden:YES animated:YES permanent:YES];
}

- (void)singleTapActions
{
    if (_exitBrowserForSingleTouchEvent) {
        [self doneButtonPressed:nil];
        return;
    }
    
    [self toggleControls];
    [self cancelSlideShow];
}

- (void)toggleControls {
    
    [self setControlsHidden:![self areControlsHidden] animated:YES permanent:YES];
}

#pragma mark - Properties

- (void)setInitialPageIndex:(NSUInteger)index {
    // Validate
    if (index >= [self numberOfPhotos]) index = [self numberOfPhotos]-1;
    self.currentPageIndex = index;
    if ([self isViewLoaded]) {
        [self jumpToPageAtIndex:index];
        if (!_viewIsActive) [self tilePages]; // Force tiling if view is not visible
    }
}

- (void)setInitialVideoOffset:(NSTimeInterval)offset
{
    _firstVideoOffset = offset;
}

#pragma mark - Misc

- (void)doneButtonPressed:(id)sender {
    //add by eric begin
    
    [self cancelControlHiding];
    [self cancelSlideShow];
    
    if ([_delegate respondsToSelector:@selector(photoBrowser:backWithMWPhoto:atIndex:)]) {
        id <MWPhoto> photo = [self photoAtIndex:_currentPageIndex];
        [_delegate photoBrowser:self backWithMWPhoto:(MWPhoto*)photo atIndex:_currentPageIndex];
    }
    //add by eric end
    
    [self dismissViewControllerAnimated:YES completion:^{
        
    }];
}



- (void)slideShow:(id)sender
{
    [self startSlideShow];
    
}

- (void)startSlideShow
{
    [self hideControls];
    isSlidingShow = YES;
    
  //  id<MWPhoto> photo = [self photoAtIndex:self.currentPageIndex];
    
    CGFloat interval = 3.0;
    NSNumber *intervalNum = [[NSUserDefaults standardUserDefaults] objectForKey:@"preview_interval_preference"];
    if (intervalNum && ![intervalNum isKindOfClass:[NSNull class]]) {
        interval = [intervalNum floatValue];
        interval = interval < 2.0 ? 2.0 : interval;
        interval = interval > 15.0 ? 15.0 : interval;
    }
    
    interval = interval / SLIDE_SHOW_INTERVAL_COUNG;
    
    _controlSlideShowTimer = [[NSTimer
                               scheduledTimerWithTimeInterval:interval
                               target:self
                               selector:@selector(slideShowScroll)
                               userInfo:nil
                               repeats:YES] retain];
}

-(void)slideShowScroll
{
}

-(BOOL)shouldSlideToNextPage
{
    id <MWPhoto> photo = [self photoAtIndex:_currentPageIndex];
    MWZoomingScrollView *page = [self pageDisplayingPhoto:photo];
    if (page){
        if ([photo underlyingImage]) return YES;
        if ([photo previewPhotoURL] && [page photoIMGView].image) {
            return YES;
        }
    }
    
    return NO;
}



-(void) forceOrietationPortrait
{
    if (self.interfaceOrientation != UIInterfaceOrientationPortrait) {
        // http://stackoverflow.com/questions/181780/is-there-a-documented-way-to-set-the-iphone-orientation
        // http://openradar.appspot.com/radar?id=697
        // [[UIDevice currentDevice] setOrientation:UIInterfaceOrientationPortrait]; // Using the following code to get around apple's static analysis...
        [[UIDevice currentDevice] performSelector:NSSelectorFromString(@"setOrientation:") withObject:(id)UIInterfaceOrientationPortrait];
    }
}

#pragma mark - Action Sheet Delegate

- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex {
    if (actionSheet == _actionsSheet) {
        
    }
    [self hideControlsAfterDelay]; // Continue as normal...
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    
    if (alertView.tag == QW_DELETE_STICKER_IMAGE_IN_BROWSER_TAG) {
        if ([_delegate respondsToSelector:@selector(photoBrowser:toggleSelectionOfPhotoAtIndex:)]) {
            [_delegate photoBrowser:self toggleSelectionOfPhotoAtIndex:_currentPageIndex];
        }
    }

    /*
#warning 斟酌
    if (alertView.tag == 1000) {
        if (buttonIndex != alertView.cancelButtonIndex) {
            OntheRoadAppDelegate *dele = appDelegate;
            dele.hasWarnedVideo = YES;
            
            [self playVideoAtPage:self.tempVideoPage];
        }
        
        self.tempVideoPage = nil;
    }
    else if (alertView.tag == QW_AUTO_PLAY_VIDEO_UNDER_3G_TAG) {
        if (buttonIndex != alertView.cancelButtonIndex) {
            [self startSlideShow];
        }
    } c
    else {
        if (buttonIndex != alertView.cancelButtonIndex) {
            if (alertView.tag == QW_REPORT_RECORD_ABUSE_ALERT_TAG) {
                MWPhoto* photo = (MWPhoto* )[self photoAtIndex:_currentPageIndex];
                if ([photo.adapter.sourceData isKindOfClass:[Record class]]) {
                    [self tipoffRecordById:[NSString stringWithFormat:@"%ld", (long)photo.adapter.itemId]];
                } else if ([photo.adapter.sourceData isKindOfClass:[QWSticker class]]) {
                    [self tipOffStickerById:photo.adapter.itemId];
                }
            } else if (alertView.tag == QW_CHECK_MAPVIEW_IN_OFFLINE_MODE_ALERT_TAG) {
                [self gotoMapView];
            } else if (alertView.tag == QW_DELETE_STICKER_IMAGE_IN_BROWSER_TAG) {
                if ([_delegate respondsToSelector:@selector(photoBrowser:toggleSelectionOfPhotoAtIndex:)]) {
                    [_delegate photoBrowser:self toggleSelectionOfPhotoAtIndex:_currentPageIndex];
                }
            }
        }
    }*/
}



#pragma mark - MBProgressHUD

- (MBProgressHUD *)progressHUD {
    if (!_progressHUD) {
        _progressHUD = [[MBProgressHUD alloc] initWithView:self.view];
        //        _progressHUD.minSize = CGSizeMake(120, 120);
        _progressHUD.minShowTime = 1;
        // The sample image is based on the
        // work by: http://www.pixelpressicons.com
        // licence: http://creativecommons.org/licenses/by/2.5/ca/
        self.progressHUD.customView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"MWPhotoBrowser.bundle/images/Checkmark.png"]] autorelease];
        [self.view addSubview:_progressHUD];
    }
    return _progressHUD;
}

- (void)showProgressHUDWithMessage:(NSString *)message {
    self.progressHUD.labelText = message;
    self.progressHUD.mode = MBProgressHUDModeIndeterminate;
    [self.progressHUD show:YES];
    self.navigationController.navigationBar.userInteractionEnabled = NO;
}

- (void)hideProgressHUD:(BOOL)animated {
    [self.progressHUD hide:animated];
    self.navigationController.navigationBar.userInteractionEnabled = YES;
}

- (void)showProgressHUDCompleteMessage:(NSString *)message {
    if (message) {
        if (self.progressHUD.isHidden) [self.progressHUD show:YES];
        self.progressHUD.labelText = message;
        self.progressHUD.mode = MBProgressHUDModeCustomView;
        [self.progressHUD hide:YES afterDelay:1.5];
    } else {
        [self.progressHUD hide:YES];
    }
    self.navigationController.navigationBar.userInteractionEnabled = YES;
}





#pragma mark Mail Compose Delegate


// ZHY: show load original image button
- (void)setDisplayLoadOriginalPhotoButton:(BOOL)displayLoadOriginalPhotoButton
{
    if (displayLoadOriginalPhotoButton != _displayLoadOriginalPhotoButton) {
        _displayLoadOriginalPhotoButton = displayLoadOriginalPhotoButton;
        id <MWPhoto> photo = [self photoAtIndex:_currentPageIndex];
        if (_displayLoadOriginalPhotoButton && [photo getCurrentPhotoType] != MWPhotoOriginal && ![photo isLoadingInProgress]) {
            
            _loadOriginBtn.hidden = NO;
        } else {
            
            _loadOriginBtn.hidden = YES;
        }
    }
}

- (void)loadOriginalPhotoBtnPressed:(id)sender
{
    id <MWPhoto> photo = [self photoAtIndex:_currentPageIndex];
    MWZoomingScrollView *page = [self pageDisplayingPhoto:photo];
    
    [page loadOriginalImage];
}

- (void)deletePhotoBtn:(id)sender
{
    if (_delegate && [_delegate respondsToSelector:@selector(photoBrowser:actionButtonPressedForPhotoAtIndex:)]) {
        [_delegate photoBrowser:self actionButtonPressedForPhotoAtIndex:_currentPageIndex];
    }
}

- (void)toggleSelectionBtnPressed:(id)sender
{
    BOOL isSuccess = YES;
    if ([_delegate respondsToSelector:@selector(photoBrowser:toggleSelectionOfPhotoAtIndex:)]) {
        isSuccess = [_delegate photoBrowser:self toggleSelectionOfPhotoAtIndex:_currentPageIndex];
    }
    
    id <MWPhoto> photo = [self photoAtIndex:_currentPageIndex];
    
    if (isSuccess) {
        [photo setIsSelected:![photo isSelected]];
    }
    
    if ([photo isSelected]) {
        [_selectionBtn setImage:[MWPhotoBrowser imageNamed:@"icon_select_60"] forState:UIControlStateNormal];
    } else {
        [_selectionBtn setImage:[MWPhotoBrowser imageNamed:@"icon_unselect_60"] forState:UIControlStateNormal];
    }
    
    [self updateDoneSelectionBtnTitle];
}

- (void)doneSelectionBtnPressed:(id)sender
{
    [self cancelControlHiding];
    [self cancelSlideShow];
    
    [self dismissViewControllerAnimated:NO
                             completion:^{
                                 if ([_delegate respondsToSelector:@selector(completeSelectionOfPhotoBrowser:)]) {
                                     [_delegate completeSelectionOfPhotoBrowser:self];
                                 }
                             }];
}

@end
